1 /* 2 Copyright: Marcelo S. N. Mancini (Hipreme|MrcSnm), 2018 - 2021 3 License: [https://creativecommons.org/licenses/by/4.0/|CC BY-4.0 License]. 4 Authors: Marcelo S. N. Mancini 5 6 Copyright Marcelo S. N. Mancini 2018 - 2021. 7 Distributed under the CC BY-4.0 License. 8 (See accompanying file LICENSE.txt or copy at 9 https://creativecommons.org/licenses/by/4.0/ 10 */ 11 12 module hip.api.graphics.color; 13 14 ///This struct is ubyte[4] or uint depending on your usages 15 struct HipColor 16 { 17 @"format" string toString() @nogc const {return "Color($r, $g, $b, $a)"; } 18 union 19 { 20 struct {ubyte r, g, b, a;} 21 ubyte[4] values; 22 uint value; 23 } 24 this(ubyte r, ubyte g, ubyte b){values = [r,g,b,255];} 25 this(ubyte r, ubyte g, ubyte b, ubyte a){values = [r,g,b,a];} 26 this(float r, float g, float b, float a){values = [cast(ubyte)(r*255),cast(ubyte)(g*255),cast(ubyte)(b*255),cast(ubyte)(a*255)];} 27 this(ubyte[4] rgba){values = rgba;} 28 this(uint rgba){values = unpackRGBA(rgba);} 29 auto opAssign(in HipColor color) 30 { 31 values[] = color.values[]; 32 return this; 33 } 34 35 static HipColor alpha(ubyte alpha){return HipColor(255, 255, 255, alpha);} 36 static HipColor alpha(float alpha){return HipColor(255, 255, 255, cast(ubyte)(alpha*255));} 37 static enum white = HipColor(0xffffffff); 38 static enum black = HipColor(0x000000ff); 39 static enum red = HipColor(0xff0000ff); 40 static enum green = HipColor(0x00ff00ff); 41 static enum blue = HipColor(0x0000ffff); 42 static enum yellow = HipColor(0xffff0000); 43 static enum purple = HipColor(0xff00ffff); 44 static enum teal = HipColor(0x00ffffff); 45 static enum no = HipColor(0x00000000); 46 47 alias values this; 48 49 HipColor lerp(HipColor to, float t) const 50 { 51 float fromT = 1.0 - t; 52 53 ushort nR = cast(ushort)(fromT*r + t*to.r); 54 ushort nG = cast(ushort)(fromT*g + t*to.g); 55 ushort nB = cast(ushort)(fromT*b + t*to.b); 56 ushort nA = cast(ushort)(fromT*a + t*to.a); 57 58 return HipColor( 59 cast(ubyte)(nR > 255 ? 255 : nR), 60 cast(ubyte)(nG > 255 ? 255 : nG), 61 cast(ubyte)(nB > 255 ? 255 : nB), 62 cast(ubyte)(nA > 255 ? 255 : nA), 63 ); 64 } 65 66 } 67 68 69 /** 70 * A struct containing a HipColor and a T which describes what color is in this T. 71 * This is useful for doing color interpolation and gradients. 72 */ 73 struct HipColorStop 74 { 75 HipColor color; 76 float t = 0; 77 } 78 79 /** 80 * 81 * Params: 82 * colorStops = A sorted array of color stops. 83 * t = What is the current T. Ranging from 0 to 1 84 * Returns: The lerped color in the stop. 85 */ 86 HipColor gradientColor(const scope ref HipColorStop[] colorStops, float t) 87 { 88 if(colorStops.length == 0) return HipColor.no; 89 if(t >= 1) return colorStops[$-1].color; 90 for(uint i = 1 ; i < colorStops.length; i++) 91 { 92 if(t > colorStops[i].t) continue; 93 float currLerpT = t / (colorStops[i].t - colorStops[i-1].t); 94 return colorStops[i-1].color.lerp(colorStops[i].color, currLerpT); 95 } 96 return colorStops[$-1].color; 97 } 98 99 /** 100 * This construct is compatible with float[4] when setting a shader variable. 101 */ 102 struct HipColorf 103 { 104 union 105 { 106 struct 107 { 108 float r =0, g = 0, b = 0, a = 0; 109 } 110 float[4] values; 111 } 112 this(HipColor c){values = [cast(float)c.r / 255, cast(float)c.g/255, cast(float)c.b/255, cast(float)c.a/255];} 113 this(float r, float g, float b, float a){values = [r,g,b,a];} 114 ubyte[4] unpackRGBA() 115 { 116 return [cast(ubyte)(r*255), cast(ubyte)(g*255), cast(ubyte)(b*255), cast(ubyte)(a*255)]; 117 } 118 119 uint toInteger() 120 { 121 ubyte red = cast(ubyte)(r*255); 122 ubyte green = cast(ubyte)(g*255); 123 ubyte blue = cast(ubyte)(b*255); 124 ubyte alpha = cast(ubyte)(a*255); 125 return packRGBA(red,green,blue,alpha); 126 } 127 128 static HipColorf fromInt(uint color) 129 { 130 ubyte[4] c = hip.api.graphics.color.unpackRGBA(color); 131 132 return HipColorf( 133 (cast(float)c[0])/255, 134 (cast(float)c[1])/255, 135 (cast(float)c[2])/255, 136 (cast(float)c[3])/255 137 ); 138 } 139 140 auto opAssign(in HipColorf color) 141 { 142 values[] = color.values[]; 143 return this; 144 } 145 146 static enum invalid = HipColorf(-1, -1, -1, -1); 147 static enum white = HipColorf(1,1,1,1); 148 static enum black = HipColorf(0,0,0,1); 149 static enum red = HipColorf(1,0,0,1); 150 static enum green = HipColorf(0,1,0,1); 151 static enum blue = HipColorf(0,0,1,1); 152 static enum yellow = HipColorf(1,1,0,1); 153 static enum purple = HipColorf(1,0,1,1); 154 static enum teal = HipColorf(0,1,1,1); 155 static enum no = HipColorf(0,0,0,0); 156 157 alias values this; 158 } 159 160 uint packRGBA(ubyte r, ubyte g, ubyte b, ubyte a) 161 { 162 return ((r << 24) + (g << 16) + (b << 8) + a); 163 } 164 165 ubyte[4] unpackRGBA(uint rgba) 166 { 167 return 168 [ 169 rgba >> 24, 170 (rgba >> 16) & 255, 171 (rgba >> 8) & 255, 172 rgba & 255 173 ]; 174 } 175 176 pragma(inline, true) 177 { 178 HipColorf color(float[4] c){ return HipColorf(c[0], c[1], c[2], c[3]); } 179 HipColorf color(float r, float g, float b, float a = 1.0){ return HipColorf(r,g,b,a); } 180 181 HipColor color(ubyte r, ubyte g, ubyte b, ubyte a = 255){return HipColor(r,g,b,a);} 182 HipColor color(uint c) 183 { 184 ubyte[4] rgba = unpackRGBA(c); 185 return HipColor(rgba[0], rgba[1], rgba[2], rgba[3]); 186 } 187 }